﻿using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;

namespace DimensionsHelper.LanguageService.Syntax;

public class CallExpression : Expression
{
    private ArgumentList? _arguments;


    private Expression _callee;

    internal CallExpression(SyntaxNode? parent, Expression callee)
        : base(SyntaxKinds.CallExpression, parent)
    {
        _callee = callee;
    }


    /// <summary>
    ///     函数调用表达式的调用方
    /// </summary>
    public Expression Callee => _callee;


    /// <summary>
    ///     获取表达式的参数列表。
    /// </summary>
    public ArgumentList? Arguments => _arguments;


    /// <summary>
    ///     获取当前已有的参数数量
    /// </summary>
    [MemberNotNullWhen(true, nameof(Arguments))]
    public bool HasArgument => _arguments is { Count: > 0 };


    public CallExpression Update(Expression callee)
    {
        SetChildField(ref _callee, IsEmptyExpression, callee);
        return this;
    }


    public CallExpression Update(ArgumentList argments)
    {
        SetChildNullableField(ref _arguments, ArgumentList.IsNullOrEmpty, argments);
        return this;
    }


    public override void AcceptVisitor<T>(SyntaxNodeVisitor<T> visitor)
    {
        Accept(visitor, Callee);

        if (HasArgument)
        {
            AcceptList(visitor, Arguments);
        }

        base.AcceptVisitor(visitor);
    }
}


public static partial class NodeFactory
{
    public static CallExpression CreateCallExpression(SyntaxNode? parent, Expression callee,
        ArgumentList? arguments)
    {
        Debug.Assert(callee.IsOneOfNode(SyntaxKinds.Identifier, SyntaxKinds.MemberExpression));
        CallExpression expr = new(parent, callee);

        if (arguments != null)
        {
            expr.Update(arguments);
        }

        return expr;
    }
}